<?php
/**
 * Created by PhpStorm.
 * Notes:鲸充(权益)接口
 * User: ymzhang
 * Date: 2022/06/28
 * Time: 15:40
 */

namespace api\channel\coupon;

use app\model\BaseSupplier;
use app\model\CouponOrder;
use think\facade\Cache;

/**
 * 鲸充(权益)
 */
class JingChongHandler extends BaseHandler
{
    /**
     * 鲸充商家编号
     * @var string $MerchantID
     */
    private $MerchantID;

    /**
     * 状态码
     * @var array $codeMsg
     */
    protected $codeMsg = [
        '101'   =>    '交易成功',
        '102'   =>    '充值中',
        '103'   =>    '可疑订单',
        '201'   =>    '参数不合法',
        '202'   =>    '签名错误',
        '203'   =>    '充值帐号不存在',
        '301'   =>    '商家不存在',
        '302'   =>    '商家已被禁用',
        '304'   =>    'IP地址不合法',
        '305'   =>    '账户余额不足',
        '306'   =>    '订单号重复',
        '307'   =>    '订单不存在',
        '401'   =>    '商品不存在',
        '405'   =>    '购买数量不合法',
        '501'   =>    '取消订单',
        '601'   =>    '渠道问题（详见状态描述）',
        '901'   =>    '未知原因（详见状态描述）',
    ];

    public function __construct()
    {
        $info = BaseSupplier::where('code', BaseSupplier::CODE_JINGCHONG)
            ->where('serv_type',PRODUCT_COUPON_SERV)
            ->cache(BaseSupplier::CODE_JINGCHONG.PRODUCT_COUPON_SERV,'3600')
            ->findOrEmpty();
        if ($info->isEmpty()) {
            return web_request([],false, 901, '渠道商配置错误');
        }
        $this->supplier = $info;
        $config = is_string($info->api_config) ? json_decode($info->api_config, true) : $info->api_config;
        $this->MerchantID = trim($config['pubId']);
        $this->key = trim($config['apikey']);
        $this->bestUrl = trim($config['bestUrl']);
        //回调地址
        $this->notifyUrl = env('app.api_url') . '/api/notify_v2/jcNotify/supplierId/' . $info['id'];
    }

    /**
     * Notes:获取鲸充商家编号
     * User: ymzhang
     * Date: 2022/06/28
     * Time: 15:45
     * @return int
     */
    public function getMerchantID()
    {
        return $this->MerchantID;
    }

    /**
     * Notes:查看商家信息(余额)
     * User: ymzhang
     * Date: 2022/06/28
     * Time: 15:50
     * @return array
     */
    public function queryMerchant()
    {
        $data = [];
        $url = $this->getBaseUrl().'QueryMerchant';
        $param = [
            'MerchantID' => $this->getMerchantID(),
            'Sign' => $this->generateSign($this->getMerchantID(),$this->getKey()),
        ];
        $res = xmlToJson(curlPost($url, $param));
        //日志记录
        if (function_exists('doLog')) {
            doLog('鲸充(权益)查询余额请求日志，' . $url . '，返回' . $res);
        }
        if (empty($res)) {
            return web_request([],false, 301, $this->getMsg(301));
        }
        $res = json_decode($res, true);
        $data['balance'] = yuan2fen($res['balance']);
        return web_request($data,true, 200, '请求成功');
    }

    /**
     * Notes:查看所有产品信息
     * User: ymzhang
     * Date: 2022/06/28
     * Time: 17:05
     * @return array
     */
    public function queryAllProduct()
    {
        $url = $this->getBaseUrl().'QueryAllProduct';
        //不需要参数
        $param = [];
        $res = xmlToJson(curlPost($url,$param));
        if (empty($res)) {
            return web_request([],false, 401, $this->getMsg(401));
        }
        $res = json_decode($res, true);
        return web_request($res['product'],true, 200, '请求成功');
    }

    /**
     * Notes:查看商品详细信息
     * User: ymzhang
     * Date: 2022/06/28
     * Time: 17:10
     * @param int $productID  商品编号
     * @return array
     */
    public function queryProductDetails(int $productID)
    {
        if (empty($productID)) {
            return web_request([],false, 204, '下单失败，商品编号不能为空');
        }
        $url = $this->getBaseUrl().'QueryProductDetails';
        $param = [
            'ProductID' => $productID,
        ];
        $res = xmlToJson(curlPost($url, $param));
        if (empty($res)) {
            return web_request([],false, 401, $this->getMsg(401));
        }
        $res = json_decode($res, true);
        return web_request($res,true, 200, '请求成功');
    }

    /**
     * Notes:购买商品
     * User: ymzhang
     * Date: 2022/06/28
     * Time: 17:10
     * @param int $data 下单参数
     * @return array
     */
    public function createOrder($order)
    {
        if (empty($order)) {
            return web_request([],false, 308, '下单信息不能为空');
        }
        if (empty($this->getMerchantID())) {
            return web_request([],false, 308, '商家编号不能为空');
        }
        if (!(isset($order['order_id']) && !empty($order['order_id'])
            && isset($order['ProductID']) && !empty($order['ProductID'])&&
            isset($order['BuyAmount']) && !empty($order['BuyAmount']))
        ) {
            return web_request([],false, 308, '请求参数错误');
        }
        //商品编号不能重复
        $info = CouponOrder::withTrashed()->where('order_id', $order['ProductID'])->findOrEmpty();
        if (!$info->isEmpty()) {
            return web_request([],false, 204, '下单失败，商品编号已存在');
        }
        //组装下单参数
        $order['MerchantID'] = $this->getMerchantID();
        $order['BuyAmount'] = isset($order['BuyAmount'])?$order['BuyAmount']:1;
        $order['ResponseUrl'] = $this->getNotifyUrl();
        $url = $this->getBaseUrl().'Pay';
        $data['MerchantID'] = $this->getMerchantID();
        $data['Sign'] = $this->generateSign($this->getMerchantID(), $data['MerchantOrderID'], $data['ProductID'], $data['BuyAmount'], $data['TargetAccount'], $this->getKey());
        $res = xmlToJson(curlPost($url, $data));
        if (empty($res)) {
            return web_request([],false, 308, '下单失败');
        }
        $res = json_decode($res, true);
        return web_request($res,false, 200, '下单成功');
    }

    /**
     * Notes:查询订单(主动发起)
     * User: ymzhang
     * Date: 2022/06/29
     * Time: 09:40
     * @param int $merchantOrderID 商家订单编号
     * @return array
     */
    public function queryOrder(int $merchantOrderID)
    {
        if (empty($merchantOrderID)) {
            return web_request([],false, 204, '商家订单编号不能为空');
        }
        $url = $this->getBaseUrl().'QueryProductDetails';
        $param = [
            'MerchantID' => $this->getMerchantID(),
            'MerchantOrderID' => $merchantOrderID,
            'Sign' => $this->generateSign($this->getMerchantID(), $merchantOrderID, $this->getKey()),
        ];
        $res = xmlToJson(curlPost($url, $param));
        $res = json_decode($res, true);
        if (empty($res) || empty($res['order-id'])) {
            return web_request([],false, 307, $this->getMsg(307));
        }
        $res['total-price'] = yuan2fen($res['total-price']);
        return web_request($res,true, 200, '请求成功');
    }

    /**
     * Notes:异步通知下单状态(服务端发起)
     * User: ymzhang
     * Date: 2022/06/29
     * Time: 10:15
     * @param int $params 验证参数
     * @return array 返回验证的签名sign
     */
    public function sycNotify($params)
    {
        if (empty($params)) {
            return web_request([],false, 201, $this->getMsg(201));
        }
        if (!(isset($params['OrderID']) && !empty($params['OrderID'])
            && isset($params['MerchantOrderID']) && !empty($params['MerchantOrderID'])
            && isset($params['State']) && !empty($params['State'])
            && isset($params['StateInfo']) && !empty($params['StateInfo'])
            && isset($params['Sign']) && !empty($params['Sign']))
        ) {
            return web_request([],false, 201, $this->getMsg(201));
        }
        if ($this->generateSign($params['OrderID'], $params['MerchantOrderID'], $params['State'], $this->getKey()) !== $params['Sign']) {
            return web_request([],false, 202, $this->getMsg(202));
        }
        unset($params['Sign']);
        return web_request(['checkSign' => $params],true, 200, '验证成功');
    }
}
